/*
 * #%L
 * SwiftUICommonUtilities
 * $Id:$
 * $HeadURL:$
 * %%
 * Copyright (C) 2011 - 2012 Linkwithweb
 * %%
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as
 * published by the Free Software Foundation, either version 3 of the 
 * License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public 
 * License along with this program.  If not, see
 * <http://www.gnu.org/licenses/gpl-3.0.html>.
 * #L%
 */
/**
 * 
 */
package com.linkwithweb.products.swiftui.utils;

/**
 * @author ashwin kumar
 *
 */
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import java.util.SimpleTimeZone;

import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang.StringUtils;

import com.linkwithweb.products.swiftui.context.SystemContext;

/**
 * This class connects to a database and dumps all the tables and contents out
 * to stdout in the form of a set of SQL executable statements
 */
public class DB2Sql {
	private static String DB_MODE = "ORACLE";

	/** Dump the whole database to an SQL string */
	public static String dumpDB(Properties props) {
		/*
		 * String driverClassName = props.getProperty("driver.class"); String
		 * driverURL = props.getProperty("driver.url");
		 */

		String driverClassName = "com.mysql.jdbc.Driver";
		String driverURL = "jdbc:mysql://localhost:3306/automata";
		String username = "automata";
		String password = "automata";

		// Default to not having a quote character
		String columnNameQuote = props.getProperty("columnName.quoteChar", "");
		DatabaseMetaData dbMetaData = null;
		Connection dbConn = null;
		try {
			Class.forName(driverClassName);
			dbConn = DriverManager.getConnection(driverURL, username, password);
			dbMetaData = dbConn.getMetaData();
		} catch (Exception e) {
			System.err.println("Unable to connect to database: " + e);
			return null;
		}

		try {
			StringBuffer result = new StringBuffer();
			// String catalog = props.getProperty("catalog");
			// String schema = props.getProperty("schemaPattern");
			// String tables = props.getProperty("tableName");
			// ResultSet rs = dbMetaData.getTables(catalog, schema, tables,
			// null);

			ResultSet rs = dbMetaData.getTables(null, "AUTOMATA", null,
					new String[] { "TABLE" });
			if (!rs.next()) {
				System.err.println("Unable to find any tables matching: ");
				rs.close();
			} else {
				// Right, we have some tables, so we can go to work.
				// the details we have are
				// TABLE_CAT String => table catalog (may be null)
				// TABLE_SCHEM String => table schema (may be null)
				// TABLE_NAME String => table name
				// TABLE_TYPE String => table type. Typical types are "TABLE",
				// "VIEW", "SYSTEM TABLE", "GLOBAL TEMPORARY",
				// "LOCAL TEMPORARY", "ALIAS", "SYNONYM".
				// REMARKS String => explanatory comment on the table
				// TYPE_CAT String => the types catalog (may be null)
				// TYPE_SCHEM String => the types schema (may be null)
				// TYPE_NAME String => type name (may be null)
				// SELF_REFERENCING_COL_NAME String => name of the designated
				// "identifier" column of a typed table (may be null)
				// REF_GENERATION String => specifies how values in
				// SELF_REFERENCING_COL_NAME are created. Values are "SYSTEM",
				// "USER", "DERIVED". (may be null)
				// We will ignore the schema and stuff, because people might
				// want to import it somewhere else
				// We will also ignore any tables that aren't of type TABLE for
				// now.
				// We use a do-while because we've already caled rs.next to see
				// if there are any rows
				do {
					String tableName = rs.getString("TABLE_NAME");
					String tableType = rs.getString("TABLE_TYPE");
					if ("TABLE".equalsIgnoreCase(tableType)) {
						result.append("\n\n-- " + tableName);
						result.append("\nDROP TABLE IF EXISTS  " + tableName
								+ "; \n");
						result.append("\nCREATE TABLE " + tableName + " (\n");
						ResultSet columnMetaData = dbMetaData.getColumns(null,
								null, tableName, "%");
						boolean firstLine = true;
						while (columnMetaData.next()) {
							if (firstLine) {
								firstLine = false;
							} else {
								// If we're not the first line, then finish the
								// previous line with a comma
								result.append(",\n");
							}
							String columnName = columnMetaData
									.getString("COLUMN_NAME");
							String columnType = columnMetaData
									.getString("TYPE_NAME");
							// WARNING: this may give daft answers for some
							// types on some databases (eg JDBC-ODBC link)
							int columnSize = columnMetaData
									.getInt("COLUMN_SIZE");
							String nullable = columnMetaData
									.getString("IS_NULLABLE");
							System.out.println(columnMetaData
									.getString("IS_AUTOINCREMENT"));
							String nullString = "NULL";
							if ("NO".equalsIgnoreCase(nullable)) {
								nullString = "NOT NULL";
							}

							result.append("    " + columnNameQuote + columnName
									+ columnNameQuote + " " + columnType + " ("
									+ columnSize + ")" + " " + nullString);
						}
						columnMetaData.close();

						// Now we need to put the primary key constraint
						try {
							// ResultSet primaryKeys =
							// dbMetaData.getPrimaryKeys(catalog, schema,
							// tableName);
							ResultSet primaryKeys = dbMetaData.getPrimaryKeys(
									null, null, tableName);
							// What we might get:
							// TABLE_CAT String => table catalog (may be null)
							// TABLE_SCHEM String => table schema (may be null)
							// TABLE_NAME String => table name
							// COLUMN_NAME String => column name
							// KEY_SEQ short => sequence number within primary
							// key
							// PK_NAME String => primary key name (may be null)
							String primaryKeyName = null;
							StringBuffer primaryKeyColumns = new StringBuffer();
							while (primaryKeys.next()) {
								String thisKeyName = primaryKeys
										.getString("PK_NAME");
								if ((thisKeyName != null && primaryKeyName == null)
										|| (thisKeyName == null && primaryKeyName != null)
										|| (thisKeyName != null && !thisKeyName
												.equals(primaryKeyName))
										|| (primaryKeyName != null && !primaryKeyName
												.equals(thisKeyName))) {
									// the keynames aren't the same, so output
									// all that we have so far (if anything)
									// and start a new primary key entry
									if (primaryKeyColumns.length() > 0) {
										// There's something to output
										result.append(",\n    PRIMARY KEY ");
										if (primaryKeyName != null) {
											result.append(primaryKeyName);
										}
										result.append("("
												+ primaryKeyColumns.toString()
												+ ")");
									}
									// Start again with the new name
									primaryKeyColumns = new StringBuffer();
									primaryKeyName = thisKeyName;
								}
								// Now append the column
								if (primaryKeyColumns.length() > 0) {
									primaryKeyColumns.append(", ");
								}
								primaryKeyColumns.append(primaryKeys
										.getString("COLUMN_NAME"));
							}
							if (primaryKeyColumns.length() > 0) {
								// There's something to output
								result.append(",\n    PRIMARY KEY ");
								if (primaryKeyName != null) {
									result.append(primaryKeyName);
								}
								result.append(" ("
										+ primaryKeyColumns.toString() + ")");
							}
						} catch (SQLException e) {
							// NB you will get this exception with the JDBC-ODBC
							// link because it says
							// [Microsoft][ODBC Driver Manager] Driver does not
							// support this function
							System.err
									.println("Unable to get primary keys for table "
											+ tableName + " because " + e);
						}

						result.append("\n);\n");

						// Right, we have a table, so we can go and dump it
						dumpTable(dbConn, result, tableName);
					}
				} while (rs.next());
				rs.close();
			}
			dbConn.close();
			return result.toString();
		} catch (SQLException e) {
			e.printStackTrace(); // To change body of catch statement use
			// Options | File Templates.
		}
		return null;
	}

	/** Dump the whole database to an SQL string */
	public static void dumpDB(Connection dbConn, StringBuffer result) {
		// Default to not having a quote character
		String columnNameQuote = "";
		DatabaseMetaData dbMetaData = null;
		try {
			dbMetaData = dbConn.getMetaData();
		} catch (Exception e) {
			System.err.println("Unable to connect to database: " + e);
		}

		try {
			// String catalog = props.getProperty("catalog");
			// String schema = props.getProperty("schemaPattern");
			// String tables = props.getProperty("tableName");
			// ResultSet rs = dbMetaData.getTables(catalog, schema, tables,
			// null);

			ResultSet rs = dbMetaData.getTables(null, "AUTOMATA", null,
					new String[] { "TABLE" });
			if (!rs.next()) {
				System.err.println("Unable to find any tables matching: ");
				rs.close();
			} else {
				// Right, we have some tables, so we can go to work.
				// the details we have are
				// TABLE_CAT String => table catalog (may be null)
				// TABLE_SCHEM String => table schema (may be null)
				// TABLE_NAME String => table name
				// TABLE_TYPE String => table type. Typical types are "TABLE",
				// "VIEW", "SYSTEM TABLE", "GLOBAL TEMPORARY",
				// "LOCAL TEMPORARY", "ALIAS", "SYNONYM".
				// REMARKS String => explanatory comment on the table
				// TYPE_CAT String => the types catalog (may be null)
				// TYPE_SCHEM String => the types schema (may be null)
				// TYPE_NAME String => type name (may be null)
				// SELF_REFERENCING_COL_NAME String => name of the designated
				// "identifier" column of a typed table (may be null)
				// REF_GENERATION String => specifies how values in
				// SELF_REFERENCING_COL_NAME are created. Values are "SYSTEM",
				// "USER", "DERIVED". (may be null)
				// We will ignore the schema and stuff, because people might
				// want to import it somewhere else
				// We will also ignore any tables that aren't of type TABLE for
				// now.
				// We use a do-while because we've already caled rs.next to see
				// if there are any rows
				do {
					String tableName = rs.getString("TABLE_NAME");
					String tableType = rs.getString("TABLE_TYPE");
					if ("TABLE".equalsIgnoreCase(tableType)) {
						// result.append("\n\n-- " + tableName);

						if (StringUtils.equalsIgnoreCase(DB_MODE, "MYSQL")) {
							result.append("\nDROP TABLE IF EXISTS  "
									+ tableName + "; \n");
						} else if (StringUtils.equalsIgnoreCase(DB_MODE,
								"ORACLE")) {
							result.append("\n BEGIN EXECUTE immediate 'drop table "
									+ tableName
									+ "'; EXCEPTION WHEN others THEN IF SQLCODE != -942 THEN RAISE; END IF; END; \r\n /");

							result.append(
									"\r\n BEGIN EXECUTE immediate 'drop sequence ")
									.append(tableName.replaceAll("frm", "")
											.replaceAll("_", ""))
									.append("_seq")
									.append("'; EXCEPTION WHEN others THEN IF SQLCODE != -942 THEN RAISE; END IF; END; \r\n /");
						}

						if (!StringUtils
								.startsWithIgnoreCase(tableName, "FRM_")) {
							continue;
						}
						/**
						 * Using Show table statement to dump table definition
						 */
						PreparedStatement stmt = dbConn
								.prepareStatement("SHOW CREATE TABLE "
										+ tableName);
						ResultSet tableRs = stmt.executeQuery();
						tableRs.next();

						String createTableStatement = tableRs.getString(2);

						/**
						 * Now try to convert as oracle string
						 * 
						 */
						boolean oracle = true;
						if (StringUtils.equalsIgnoreCase(DB_MODE, "ORACLE")) {
							createTableStatement = createTableStatement
									.replaceAll("`", "")
									.replaceAll("int\\(10\\)", "number")
									.replaceAll("bigint", "number")
									.replaceAll(" unsigned", "")
									.replaceAll(" AUTO_INCREMENT", "");

							createTableStatement = createTableStatement
									.replaceAll("varchar\\(", "varchar2(")
									.replaceAll(" text", " clob");

							createTableStatement = createTableStatement
									.replaceAll("datetime", "timestamp");

							createTableStatement = createTableStatement
									.replaceAll("tinyint", "char");

							int primaryKeyIndex = createTableStatement
									.indexOf("PRIMARY KEY");
							int primaryKeyEndIndex = createTableStatement
									.indexOf(")", primaryKeyIndex);

							String primaryKey = createTableStatement.substring(
									primaryKeyIndex + "PRIMARY KEY (".length(),
									primaryKeyEndIndex);

							createTableStatement = createTableStatement
									.replaceAll("PRIMARY KEY", "constraint "
											+ tableName + "_pk primary key");

							createTableStatement = findAndReplaceLineEndWith(
									createTableStatement, "COMMENT", ",");
							
							createTableStatement = findAndReplaceLineEndWith(
									createTableStatement, "DEFAULT ", ",");

							createTableStatement = findAndReplaceLineEndWith(
									createTableStatement, "ENGINE", ";");

							createTableStatement = createTableStatement
									+ "\r\n"
									+ "create sequence "
									+ tableName.replaceAll("frm", "")
											.replaceAll("_", "")
									+ "_seq start with 1 increment by 1;\r\n"
									+ "create or replace trigger "
									+ tableName.replaceAll("frm", "")
											.replaceAll("_", "")
									+ "_insert \r\n before insert on "
									+ tableName
									+ " \r\n REFERENCING NEW AS NEW \r\n for each row \r\n begin \r\nselect "
									+ tableName.replaceAll("frm", "")
											.replaceAll("_", "")
									+ "_seq.nextval into :new." + primaryKey
									+ " from dual; \r\n end; \r\n /";

						}

						result.append("\r\n").append(createTableStatement)
								.append("\r\n");
						tableRs.close();

						// Right, we have a table, so we can go and dump it
						dumpTable(dbConn, result, tableName);
					}
				} while (rs.next());
				rs.close();
			}
			dbConn.close();
		} catch (SQLException e) {
			e.printStackTrace(); // To change body of catch statement use
			// Options | File Templates.
		}
	}

	/**
	 * @param createTableStatement
	 * @param string
	 * @param string2
	 * @return
	 */
	private static String findAndReplaceLineEndWith(
			String createTableStatement, String findString, String replaceWith) {
		StringBuffer returnString = new StringBuffer();

		for (String line : createTableStatement.split("\n")) {
			int findStringIndex = line.indexOf(findString);
			if (findStringIndex != -1) {
				returnString.append(line.substring(0, findStringIndex))
						.append(replaceWith).append("\r\n");
			} else {
				returnString.append(line).append("\n");
			}
		}

		return returnString.toString();
	}

	public void createTableDef() {
		/*
		 * 
		 * result.append("\nCREATE TABLE " + tableName + " (\n"); ResultSet
		 * tableMetaData = dbMetaData.getColumns(null, null, tableName, "%");
		 * boolean firstLine = true; while (tableMetaData.next()) { if
		 * (firstLine) { firstLine = false; } else { // If we're not the first
		 * line, then finish the // previous line with a comma
		 * result.append(",\n"); } String columnName =
		 * tableMetaData.getString("COLUMN_NAME"); String columnType =
		 * tableMetaData.getString("TYPE_NAME"); // WARNING: this may give daft
		 * answers for some // types on some databases (eg JDBC-ODBC link) int
		 * columnSize = tableMetaData.getInt("COLUMN_SIZE"); String nullable =
		 * tableMetaData.getString("IS_NULLABLE"); String nullString = "NULL";
		 * if ("NO".equalsIgnoreCase(nullable)) { nullString = "NOT NULL"; }
		 * String autoIncrementedColumn = ""; if
		 * (getAutoIncrementedColumns(dbConn, tableName).contains(columnName)) {
		 * autoIncrementedColumn = "AUTO_INCREMENT"; }
		 * 
		 * if (StringUtils.containsIgnoreCase(columnType, "unsigned")) { if
		 * (StringUtils.containsIgnoreCase(columnType, "date") ||
		 * StringUtils.containsIgnoreCase(columnType, "time")) {
		 * result.append("    " + columnNameQuote + columnName + columnNameQuote
		 * + " " + columnType.replaceAll(" unsigned", "") + " unsigned" + " " +
		 * nullString + " " + autoIncrementedColumn); } else {
		 * result.append("    " + columnNameQuote + columnName + columnNameQuote
		 * + " " + columnType.replaceAll(" unsigned", "") + " (" + columnSize +
		 * ") unsigned" + " " + nullString + " " + autoIncrementedColumn); }
		 * 
		 * } else { if (StringUtils.containsIgnoreCase(columnType, "date") ||
		 * StringUtils.containsIgnoreCase(columnType, "time")) {
		 * result.append("    " + columnNameQuote + columnName + columnNameQuote
		 * + " " + columnType + " " + nullString + " " + autoIncrementedColumn);
		 * } else { result.append("    " + columnNameQuote + columnName +
		 * columnNameQuote + " " + columnType + " (" + columnSize + ")" + " " +
		 * nullString + " " + autoIncrementedColumn); } } }
		 * tableMetaData.close();
		 * 
		 * // Now we need to put the primary key constraint try { // ResultSet
		 * primaryKeys = // dbMetaData.getPrimaryKeys(catalog, schema, //
		 * tableName); ResultSet primaryKeys = dbMetaData.getPrimaryKeys(null,
		 * null, tableName); // What we might get: // TABLE_CAT String => table
		 * catalog (may be null) // TABLE_SCHEM String => table schema (may be
		 * null) // TABLE_NAME String => table name // COLUMN_NAME String =>
		 * column name // KEY_SEQ short => sequence number within primary // key
		 * // PK_NAME String => primary key name (may be null) String
		 * primaryKeyName = null; StringBuffer primaryKeyColumns = new
		 * StringBuffer(); while (primaryKeys.next()) { String thisKeyName =
		 * primaryKeys.getString("PK_NAME"); if ((thisKeyName != null &&
		 * primaryKeyName == null) || (thisKeyName == null && primaryKeyName !=
		 * null) || (thisKeyName != null && !thisKeyName.equals(primaryKeyName))
		 * || (primaryKeyName != null && !primaryKeyName.equals(thisKeyName))) {
		 * // the keynames aren't the same, so output // all that we have so far
		 * (if anything) // and start a new primary key entry if
		 * (primaryKeyColumns.length() > 0) { // There's something to output
		 * result.append(",\n    PRIMARY KEY "); if (primaryKeyName != null) {
		 * result.append(primaryKeyName); } result.append("(" +
		 * primaryKeyColumns.toString() + ")"); } // Start again with the new
		 * name primaryKeyColumns = new StringBuffer(); primaryKeyName =
		 * thisKeyName; } // Now append the column if
		 * (primaryKeyColumns.length() > 0) { primaryKeyColumns.append(", "); }
		 * primaryKeyColumns.append(primaryKeys.getString("COLUMN_NAME")); } if
		 * (primaryKeyColumns.length() > 0) { // There's something to output
		 * result.append(",\n    PRIMARY KEY "); if (primaryKeyName != null) {
		 * result.append(primaryKeyName.replaceAll("PRIMARY", "")); }
		 * result.append(" (" + primaryKeyColumns.toString() + ")"); } } catch
		 * (SQLException e) { // NB you will get this exception with the
		 * JDBC-ODBC // link because it says // [Microsoft][ODBC Driver Manager]
		 * Driver does not // support this function
		 * System.err.println("Unable to get primary keys for table " +
		 * tableName + " because " + e); }
		 * 
		 * result.append("\n);\n");
		 */
	}

	public static List<String> getAutoIncrementedColumns(Connection dbConn,
			String table) {
		List<String> columnNames = new ArrayList<String>();
		try {
			Statement statement = dbConn.createStatement();
			ResultSet result = statement.executeQuery("Select * from " + table
					+ " where 1=2");
			int columnCount = result.getMetaData().getColumnCount();
			for (int i = 1; i <= columnCount; i++) {
				if (result.getMetaData().isAutoIncrement(i)) {
					columnNames.add(result.getMetaData().getColumnName(i));
				}
			}

		} catch (SQLException e) {

			e.printStackTrace();
		}

		return columnNames;
	}

	/** dump this particular table to the string buffer */
	private static void dumpTable(Connection dbConn, StringBuffer result,
			String tableName) {
		try {
			// First we output the create table stuff
			PreparedStatement stmt = dbConn.prepareStatement("SELECT * FROM "
					+ tableName);
			ResultSet rs = stmt.executeQuery();
			ResultSetMetaData metaData = rs.getMetaData();
			int columnCount = metaData.getColumnCount();

			// Now we can output the actual data
			// result.append("\n-- \n-- Data for " + tableName + "\n");
			while (rs.next()) {
				result.append("INSERT INTO " + tableName + " VALUES (");
				for (int i = 0; i < columnCount; i++) {
					if (i > 0) {
						result.append(", ");
					}
					String columnTypeName = metaData.getColumnTypeName(i + 1);
					Object value = null;
					if (StringUtils.containsIgnoreCase(columnTypeName, "date")
							|| StringUtils.containsIgnoreCase(columnTypeName,
									"time")) {
						try {
							value = rs.getDate(i + 1);

							if (StringUtils.equalsIgnoreCase(DB_MODE, "ORACLE")) {
								// value = "TIMESTAMP "
								// + getDateString((Date)
								// value,"yyyy-MM-dd hh:mm:ss");
								value = "to_timestamp('"
										+ getDateString((Date) value,
												"yyyy-MM-dd hh:mm:ss")
										+ "','YYYY-MM-DD hh:mi:ss')";

							} else {
								value = getDateString((Date) value,
										"yyyy-MM-dd hh:mm:ss");
							}

						} catch (Exception e) {
							try {
								value = rs.getString(i + 1);
							} catch (Exception e2) {
								value = null;
							}

						}
					} else if (StringUtils.containsIgnoreCase(columnTypeName,
							"int")
							|| StringUtils.containsIgnoreCase(columnTypeName,
									"number")) {
						value = rs.getObject(i + 1);

					} else {
						value = rs.getObject(i + 1);
					}
					if (value == null) {
						result.append("NULL");
					} else {
						String outputValue = value.toString();
						if (value instanceof Boolean) {
							if ((Boolean) value) {
								outputValue = "1";
							} else {
								outputValue = "0";
							}
						}

						if (value instanceof Integer || value instanceof Long
								|| value instanceof Double
								|| value instanceof BigDecimal
								|| value instanceof Float) {
							result.append(outputValue);
						} else if (StringUtils.containsIgnoreCase(outputValue,
								"to_timestamp")) {
							result.append(outputValue);
						} else {
							result.append("'"
									+ StringEscapeUtils.escapeSql(outputValue)
									+ "'");
						}
					}
				}
				result.append(") ; \r\n");
			}
			rs.close();
			stmt.close();
		} catch (SQLException e) {
			System.err.println("Unable to dump table " + tableName
					+ " because: " + e);
			e.printStackTrace();
		}
	}

	/**
	 * @param file
	 */
	public static String backupDB(String file, Connection dbConn) {
		String userHome = System.getProperty("user.home");
		String backupDirectory = "";

		try {
			backupDirectory = userHome
					+ "/.swiftui/framework/backups/"
					+ SystemContext.getInstance().getUserContext()
							.getIdentifier() + "/";
		} catch (Exception e) {
			backupDirectory = userHome + "/.swiftui/framework/backups/local/";
		}

		File backupDir = new File(backupDirectory);
		if (!backupDir.exists()) {
			backupDir.mkdirs();
		}
		String backupFile = backupDirectory
				+ getDateString(Calendar.getInstance().getTime(),
						"yyyyMMddhhmmss") + "_" + file;

		try {
			FileOutputStream fos = new FileOutputStream(backupFile);
			StringBuffer result = new StringBuffer();
			dumpDB(dbConn, result);
			fos.write(result.toString().getBytes());
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return backupFile;
	}

	protected static String getDateString(Date dateObject, String format) {
		String returnString = "";
		Date newDate = new Date();
		try {

			SimpleDateFormat formatter;
			formatter = new SimpleDateFormat(format);
			java.util.Calendar cal = Calendar.getInstance(new SimpleTimeZone(0,
					"GMT"));
			formatter.setCalendar(cal);

			returnString = formatter.format(dateObject);
			// System.out.println(formatter.format(newDate));
		} catch (Exception e) {
			// TODO Auto-generated catch block
		}

		return returnString;
	}

	private static String convertToHex(byte[] data) {
		StringBuffer buf = new StringBuffer();
		for (int i = 0; i < data.length; i++) {
			int halfbyte = (data[i] >>> 4) & 0x0F;
			int two_halfs = 0;
			do {
				if ((0 <= halfbyte) && (halfbyte <= 9))
					buf.append((char) ('0' + halfbyte));
				else
					buf.append((char) ('a' + (halfbyte - 10)));
				halfbyte = data[i] & 0x0F;
			} while (two_halfs++ < 1);
		}
		return buf.toString();
	}

	public static String MD5(String text) throws NoSuchAlgorithmException,
			UnsupportedEncodingException {
		MessageDigest md;
		md = MessageDigest.getInstance("MD5");
		byte[] md5hash = new byte[32];
		md.update(text.getBytes("iso-8859-1"), 0, text.length());
		md5hash = md.digest();
		return convertToHex(md5hash);
	}

	/** Main method takes arguments for connection to JDBC etc. */
	public static void main(String[] args) {
		String driverClassName = "com.mysql.jdbc.Driver";
		String driverURL = "jdbc:mysql://localhost:13306/automata";
		String username = "automata";
		String password = "automata";

		// Default to not having a quote character
		Connection dbConn = null;
		try {
			Class.forName(driverClassName);
			dbConn = DriverManager.getConnection(driverURL, username, password);

			backupDB("dump.sql", dbConn);
		} catch (Exception e) {
			System.err.println("Unable to connect to database: " + e);
		}

	}
}